#ifndef GEOMETRY_BUILDER_H
#define GEOMETRY_BUILDER_H

#include "../core/AbstractObject.h"
#include <sstream>
#include "Horde3D.h"
#include "Horde3DUtils.h"

#define H3DPACK_FLOAT 1
#define H3DPACK_SHORT 2
#define H3DPACK_ICHAR 3
#define H3DPACK_FCHAR 4

#define H3DGEOSTREAM_POS 0
#define H3DGEOSTREAM_NORM 1
#define H3DGEOSTREAM_TAN 2
#define H3DGEOSTREAM_BITAN 3
#define H3DGEOSTREAM_JIND 4
#define H3DGEOSTREAM_WEIGHTS 5
#define H3DGEOSTREAM_TEX0 6
#define H3DGEOSTREAM_TEX1 7

#define H3D_GEO_BUILDER_MAX_STREAMS 8

class H3DGeoStream
{
public:
	int streamID;
	int packType;
	int packElements;
	bool active;
	std::vector<double> values;
	int idx;

	void push(double val1);
	void push(double val1, double val2);
	void push(double val1, double val2, double val3);
	void push(double val1, double val2, double val3, double val4);

	void fillTo(int fidx, double val = 0.0);
	void writestream(std::stringstream& ss);
	void clear();
};

class MeshStub
{
public:
	std::string name;
	int vstart;
	int vend;
	int istart;
	int icount;
	H3DRes material;
};

//OBJTYPE H3DGeometryBuilder
class H3DGeometryBuilder : public AbstractObject
{
public:
	H3DGeometryBuilder();

	// Return the c++ type as a string 
	virtual std::string getCppTypeName();

	// returns a description of this thing
	virtual std::string getDescription();

	// create another one of these
	virtual AbstractObject* newInstance();

	// init & update
	virtual void init();
	virtual void update(double dt);

	// push its static functions into the given lua table
	virtual void pushStaticFuncs(lua_State* L);

	virtual ~H3DGeometryBuilder();

	// Interface
	//LIAG_THESE
	void clear();
	void makeMesh(std::string meshName, H3DRes material);
	H3DNode buildModel(H3DNode parent, std::string modelName, std::string geoResName);

	void makeTriangles();
	void makeQuads();
	void rawIdxTriangle(int idx1, int idx2, int idx3);

	void vposition(double x, double y, double z);
	void vtexcoords(double u, double v);
	void vtexcoords0(double u, double v);
	void vtexcoords1(double u, double v);
	void vnormal(double nx, double ny, double nz);
	void vtangent(double tx, double ty, double tz);
	void vbitangent(double tx, double ty, double tz);
	void vweights(double w1, double w2, double w3, double w4);
	void vjindices(int i1, int i2, int i3, int i4);
	//STOP_LIAG

private:
	void setStream(int sid, int magicId, int packType, int packElements);
	int equalizeStreams();

	std::vector<MeshStub> _meshes;
	H3DGeoStream _streams[H3D_GEO_BUILDER_MAX_STREAMS];
	int _vstart;
	int _vused;
	int _istart;
	std::vector<int> _indices;
};

#endif